//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package feedback_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/proto-gen-go.git/feedback_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
)

type FeedBackApiImpl struct {
	feedback_api.UnimplementedFeedBackApiServer
}

func (apiImpl *FeedBackApiImpl) Add(ctx context.Context, req *feedback_api.AddRequest) (*feedback_api.AddResponse, error) {
	userId := ""
	if req.SessionId != "" {
		sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
		if ok {
			userId = sessionItem.UserId
		}
	}

	feedBackId := uuid.NewString()
	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = dao.FeedBackDao.Insert(sessCtx, &dao.FeedBackInfoDbItem{
			FeedBackId: feedBackId,
			Content:    req.Content,
			UserId:     userId,
			TimeStamp:  nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &feedback_api.AddResponse{
			Code:       feedback_api.AddResponse_CODE_OK,
			FeedBackId: feedBackId,
		}, nil
	})

	if err != nil {
		return nil, err
	}
	return ret.(*feedback_api.AddResponse), nil
}

func (apiImpl *FeedBackApiImpl) List(ctx context.Context, req *feedback_api.ListRequest) (*feedback_api.ListResponse, error) {
	emptyList := []*feedback_api.FeedBackInfo{}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &feedback_api.ListResponse{
			Code:     feedback_api.ListResponse_CODE_WRONG_SESSION,
			ErrMsg:   "会话不存在",
			InfoList: emptyList,
		}, nil
	}
	count, err := dao.FeedBackDao.Count(ctx, true, sessionItem.UserId)
	if err != nil {
		return nil, err
	}
	feedBackItemList, err := dao.FeedBackDao.List(ctx, true, sessionItem.UserId, int64(req.Offset), int64(req.Limit))
	if err != nil {
		return nil, err
	}
	feedBackList := []*feedback_api.FeedBackInfo{}
	for _, feedBackItem := range feedBackItemList {
		feedBack := feedBackItem.ToFeedBackInfo()
		feedBack.UserDisplayName = sessionItem.DisplayName
		feedBack.UserLogoUri = sessionItem.LogoUri
		feedBackList = append(feedBackList, feedBack)
	}

	return &feedback_api.ListResponse{
		Code:       feedback_api.ListResponse_CODE_OK,
		TotalCount: count,
		InfoList:   feedBackList,
	}, nil
}

func (apiImpl *FeedBackApiImpl) Remove(ctx context.Context, req *feedback_api.RemoveRequest) (*feedback_api.RemoveResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &feedback_api.RemoveResponse{
			Code:   feedback_api.RemoveResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = dao.FeedBackDao.Remove(sessCtx, req.FeedBackId, sessionItem.UserId)
		if err != nil {
			return nil, err
		}
		return &feedback_api.RemoveResponse{
			Code: feedback_api.RemoveResponse_CODE_OK,
		}, nil
	})

	if err != nil {
		return nil, err
	}
	return ret.(*feedback_api.RemoveResponse), nil
}
